<html>
<head><meta charset="utf-8"><title>simd support · miri · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/index.html">miri</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html">simd support</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="233947351"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233947351" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233947351">(Apr 10 2021 at 11:16)</a>:</h4>
<p>Hello! I am the maintainer of a crate that uses simd instructions and i'd like to be able run tests with miri however I understand that it's not supported right now.<br>
I stumbled upon <a href="https://github.com/rust-lang/miri/issues/662">https://github.com/rust-lang/miri/issues/662</a> but it's not really clear what needs to be done or what is the status of things.<br>
If implementing support for SIMD instructions is possible somehow, I am willing to invest some of my free time to help  but I have <em>no idea</em> where to start.<br>
Would all simd intrinsincs have to have "faked" using scalar based algorithm for each intrinsic? Additionally would that be somehow possible with std::simd <a href="https://github.com/rust-lang/stdsimd">https://github.com/rust-lang/stdsimd</a> ?</p>



<a name="233948185"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233948185" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233948185">(Apr 10 2021 at 11:32)</a>:</h4>
<p><span class="user-mention" data-user-id="281572">@marmeladema</span> your message comes at a great time. :)</p>



<a name="233948238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233948238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233948238">(Apr 10 2021 at 11:33)</a>:</h4>
<p>I am currently attending the Rust Verification Workshop at ETAPS, and many people there working on analyzing Rust code are running into the problem of supporting SIMD intrinsics. So an effort is forming to provide a <em>pure Rust</em> implementation of (a subset of) those intrinsics.</p>



<a name="233948281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233948281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233948281">(Apr 10 2021 at 11:34)</a>:</h4>
<p><span class="user-mention" data-user-id="336739">@Alastair Reid</span> posted some first results at <a href="https://github.com/alastairreid/rust-verification-tools/blob/llvm_opt/runtime/src/x86intrinsics.rs">https://github.com/alastairreid/rust-verification-tools/blob/llvm_opt/runtime/src/x86intrinsics.rs</a></p>



<a name="233948426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233948426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233948426">(Apr 10 2021 at 11:36)</a>:</h4>
<p>so I think the way forward here is:</p>
<ul>
<li>probably move those intrinsics to a separate git repo so we can more easily share them between the various MIR-based tools</li>
<li>figure out how to hook those Rust implementations into Miri... my current thinking is to do this "inside" the machine, i.e., to build a crate with all those intrinsic implementations as part of the sysroot and load their MIR whenever Miri needs to interpret an intrinsic. Other approaches might also be possible.</li>
<li>implement more intrinsics. :D</li>
</ul>



<a name="233949548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233949548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233949548">(Apr 10 2021 at 11:57)</a>:</h4>
<p>Great! I am really looking forward to help! Not sure how much I can do but i'll definitely try!<br>
From the link you shared it seems that for miri, the intrinsics need to be implemented using a scalar equivalent. I will check but I <em>think</em> the std::simd working group also needs to do that to support some operations not available on a specific architecture/platform. Maybe both working group need to work together to implement the scalar version of intrinsics? I understand that the main difference is that miri will want to handle target specific intrinsics and that std::simd is focused toward "generic" simd types/operations. But I feel like the scalar implementation of those will be the same or very close to each other</p>



<a name="233949804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233949804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233949804">(Apr 10 2021 at 12:01)</a>:</h4>
<p>Yeah, we haven't reached out to the Rust SIMD people for this yet (or even checked who would be the right group to reach out to). This just started 2 days ago.^^</p>



<a name="233950148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233950148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233950148">(Apr 10 2021 at 12:06)</a>:</h4>
<p>Oh right ok sorry^^ it's very new then :-D I am very enthusiastic about it</p>



<a name="233950325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233950325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233950325">(Apr 10 2021 at 12:08)</a>:</h4>
<p>One related project that might be of interest is <a href="https://github.com/simd-everywhere/simde">https://github.com/simd-everywhere/simde</a></p>



<a name="233950715"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233950715" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233950715">(Apr 10 2021 at 12:15)</a>:</h4>
<p>yeah, such projects certainly already exist for C, but that is not very useful for MIR-based tools</p>



<a name="233950785"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233950785" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233950785">(Apr 10 2021 at 12:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="281572">marmeladema</span> <a href="#narrow/stream/269128-miri/topic/simd.20support/near/233950148">said</a>:</p>
<blockquote>
<p>Oh right ok sorry^^ it's very new then :-D I am very enthusiastic about it</p>
</blockquote>
<p>if you don't mind joining another Zulip, <a href="https://rust-verify.zulipchat.com/#narrow/stream/284566-general/topic/cfg.28miri.29.20and.20avoiding.20SIMD">here is the thread</a> where discussion happened so far.</p>



<a name="233950805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233950805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233950805">(Apr 10 2021 at 12:16)</a>:</h4>
<p>You seem to know more about std::simd so bringing together the right people there could also help :)</p>



<a name="233957212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233957212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233957212">(Apr 10 2021 at 13:58)</a>:</h4>
<p>There's also an accepted compiler MCP about this for cranelift. Please keep <span class="user-mention" data-user-id="133247">@bjorn3</span> in the loop</p>



<a name="233958826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233958826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233958826">(Apr 10 2021 at 14:21)</a>:</h4>
<p>that would be <a href="https://github.com/rust-lang/compiler-team/issues/381">https://github.com/rust-lang/compiler-team/issues/381</a> I guess -- thanks for pointing that out!</p>



<a name="233975270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233975270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233975270">(Apr 10 2021 at 18:12)</a>:</h4>
<p>I participate in the simd group, its likely easy to add support for the intrinsics we need to miri, since there are only a few and they're pretty straightforward (just <a href="https://github.com/rust-lang/stdsimd/blob/master/crates/core_simd/src/intrinsics.rs#L10-L69">https://github.com/rust-lang/stdsimd/blob/master/crates/core_simd/src/intrinsics.rs#L10-L69</a>). IDT we're confident the set we have now is the complete set, so if you added them now you'd potentially have to add more later.</p>



<a name="233978222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233978222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233978222">(Apr 10 2021 at 18:54)</a>:</h4>
<p>but if we added those we'd still not support programs using <code>std::arch</code> directly, right?<br>
is the idea that long-term, those will all move to <code>std::simd</code>?<br>
for purposes of Miri or other verification tools, would it make sense to implement <code>std::arch</code> on top of these intrinsics, and how hard would that be?</p>



<a name="233979982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233979982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233979982">(Apr 10 2021 at 19:20)</a>:</h4>
<p>in the long term std::arch and std::simd will <strong>very likely</strong> continue to be separate forever.</p>
<p>the reason being basically that std::arch has overlap with <em>one monomorphization</em> of what you'd get from std::simd, however std::arch is also providing things that std::simd never will (usually because a given op is exclusive to a given arch) and also std::arch is already fairly filled out and moving it to be std::simd internally would be a lot of work for no gain.</p>



<a name="233985208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233985208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233985208">(Apr 10 2021 at 20:41)</a>:</h4>
<p>Part of the functions implemented in std::arch use the same "platform-intrinsic"s used by std::simd. Those would trivially be supported. Others are implemented directly using llvm intrinsics. Those could be roughly devided into three groups: Those that can be trivially changed to use "platform-intrinsic"s or for example <code>core::intrinics::load_unaligned</code>. Those that should likely get new "platform-intrinsics"s and those that will likely need to keep using llvm intrinsics. The last group is mostly for float intrinsics where edge cases are handled differently between architectures.</p>



<a name="233985231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233985231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233985231">(Apr 10 2021 at 20:41)</a>:</h4>
<p>For a list of llvm intrinsics cg_cluf needs to emulate to support the rand and regex crates see: <a href="https://github.com/bjorn3/rustc_codegen_cranelift/blob/53bfc6729ae4a53c8092473452de7a272224df5d/src/intrinsics/llvm.rs">https://github.com/bjorn3/rustc_codegen_cranelift/blob/53bfc6729ae4a53c8092473452de7a272224df5d/src/intrinsics/llvm.rs</a></p>



<a name="233986322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/233986322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#233986322">(Apr 10 2021 at 20:57)</a>:</h4>
<p>There could also be different milestone of simd support in miri. It seems that programs relying on std::simd could be supported by miri "out-of-the-box" by relying on the scalar version of the operations?</p>



<a name="234035593"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234035593" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234035593">(Apr 11 2021 at 10:52)</a>:</h4>
<p><span class="user-mention" data-user-id="281572">@marmeladema</span> do you have a concrete crate/piece of code in mind that you want to get working with Miri?<br>
FWIW, some of the portable simd intrinsics should <a href="https://github.com/rust-lang/rust/blob/ba6275b6a9fc05fd5d93220e9a67fe64d663cb62/compiler/rustc_mir/src/interpret/intrinsics.rs#L414">already work</a> in Miri</p>



<a name="234035758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234035758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234035758">(Apr 11 2021 at 10:55)</a>:</h4>
<p>The crate i'd like to run miri on is <a href="https://github.com/cloudflare/sliceslice-rs">https://github.com/cloudflare/sliceslice-rs</a> and especially the code that relies on simd instructions is at <a href="https://github.com/cloudflare/sliceslice-rs/blob/master/src/x86.rs#L50-L127">https://github.com/cloudflare/sliceslice-rs/blob/master/src/x86.rs#L50-L127</a><br>
All the operations are pretty common and I will investigate soon if/how we could use std::simd instead.</p>



<a name="234035851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234035851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234035851">(Apr 11 2021 at 10:57)</a>:</h4>
<p>okay so this is using <code>std::arch</code>, I see</p>



<a name="234035862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234035862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234035862">(Apr 11 2021 at 10:57)</a>:</h4>
<p>yeah hasbrown would also need that I think (currently it uses <code>cfg(miri)</code> and then takes the scalar fallback path)</p>



<a name="234212488"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234212488" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alastair Reid <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234212488">(Apr 12 2021 at 19:02)</a>:</h4>
<p>It looks as if the only vector functions that actually use LLVM intrinsics in the cloudflare code are _mm256_movemask_epi8 and _mm256_cmpeq_epi8.<br>
The others either use the processor-neutral simd operations like simd_and (_mm_256_and), or non-vector operations (_mm256_loadu_si256).</p>
<p>My SIMD operation emulation library implements enough of these that I am able to generate LLVM bitcode files that don't use x86-specific intrinsics.<br>
I could then run the example from the sliceslice README file in the KLEE symbolic execution tool.<br>
(More precisely, I have a tool that can replace calls to any x86 intrinsics with calls to functions from my emulation library.)<br>
The library is the same one that Ralf linked to at the top - but cleaned up, moved to a different branch, etc. <a href="https://github.com/alastairreid/rust-verification-tools/blob/simd/simd_intrinsics/src/lib.rs">https://github.com/alastairreid/rust-verification-tools/blob/simd/simd_intrinsics/src/lib.rs</a></p>
<p>To make this work with miri, I suspect that you would need:</p>
<ul>
<li>to have miri use functions from the simd emulation library when it finds simd intrinsics being used</li>
<li>to have a suitable way of converting from the intrinsic names in MIR to the name of the emulation function<ul>
<li>for the x86-specific intrinsics, this is easy: <a href="http://llvm.x86.sse2.foo">llvm.x86.sse2.foo</a> is implemented by llvm_x86_sse2_foo (i.e., just replace the underscores)</li>
<li>for the generic intrinsics like "simd_and", I suspect that you would need to use the vector length to produce a unique name (eg "simd_and_128")</li>
</ul>
</li>
<li>for the generic intrinsics, implement the appropriate emulation function</li>
</ul>
<p>For simd_and_128, this would be something like</p>
<div class="codehilite"><pre><span></span><code>#[inline]
#[no_mangle]
extern &quot;C&quot; fn simd_and_128(a: simd16&lt;u8&gt;, b: simd16&lt;u8&gt;) -&gt; simd16&lt;u8&gt; {
    lift16_vv_v(u8::and, a, b)
}
</code></pre></div>
<p>and then add a wrapper that makes the types look like Intel official types</p>
<div class="codehilite"><pre><span></span><code>mod with_intel_official_types { // I was not feeling very imaginative about this module name :-)
    ...
    fn simd_and_128(a: __m128i, b: __m128i) -&gt; __m128i {
        let a = unsafe { std::mem::transmute::&lt;__m128i, super::simd16&lt;u8&gt;&gt;(a) };
        let b = unsafe { std::mem::transmute::&lt;__m128i, super::simd16&lt;u8&gt;&gt;(b) };
        let r = super::simd_and_128(a, b);
        unsafe { std::mem::transmute::&lt;super::simd16&lt;u8&gt;, __m128i&gt;(r) }
    }
    ...
}
</code></pre></div>
<p>[Note: this 128 bit version is for SSE2 vectors. I haven't done much of AVX2 yet because most libraries can be built with AVX2 disabled so it is not as pressing for me as SSE2 which cannot be disabled without LLVM deciding to wake the x87 FPU from its slumber.<br>
Note also that I randomly chose to treat the operation as being made of 16 8-bit and operations. I could also have used 8 16-bit ands, 4 32-bit ands or 2 64-bit ands.]</p>



<a name="234236325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234236325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234236325">(Apr 12 2021 at 21:48)</a>:</h4>
<p>I typed way more like <del>3</del> <del>4</del> 5 (wtf...) times and zulip <a href="https://github.com/zulip/zulip/issues/18113">ate it</a> each time, so I'll keep it short:</p>
<ul>
<li>
<p>I think it would be good for miri to support up to SSE2 on intel. Code using this is often hairy, and would be nice to be able to test under miri. SSE2 is a good cutoff point since it's part of the x86_64 baseline, and not too complex — anything else could just say false to <code>std::is_x86_feature_detected</code>.</p>
</li>
<li>
<p>Anything hard to support (nontemporal ops probably require another, separate, data race detector to detect UB for and are very rarely used) should probably just be unsupported.</p>
</li>
<li>
<p>Ideally it would be from an external crate, and done in such a way so that supporting these doesn't increase miri's maintenance burden substantially.</p>
</li>
<li>
<p>project-portable-simd will never replace all of these, it only handles cases well supported by all arches, or that would be strange if missing.</p>
<p>We should expect that code will continue to use stdarch forever, for cases where the portable simd functionality isn't no_std (one example of several: sqrt likely will require libstd for the fallback — not all arches have an intrinsic for sqrt), and for cases where one arch has a useful intrinsic that nothing else has (I used _mm_madd_epi16 the other day — it's one of the very rare fast horizontal operations on any simd ISA)</p>
</li>
<li>
<p>All that said, I'd completely understand not wanting to do this, and had always assumed it was out of scope for miri</p>
</li>
</ul>



<a name="234516924"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234516924" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alastair Reid <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234516924">(Apr 14 2021 at 15:11)</a>:</h4>
<p>Minor update on what I wrote above:</p>
<ul>
<li>I pushed a new version just now (same location: <a href="https://github.com/alastairreid/rust-verification-tools/blob/simd/simd_intrinsics/src/lib.rs">https://github.com/alastairreid/rust-verification-tools/blob/simd/simd_intrinsics/src/lib.rs</a>)<ul>
<li>It uses traits in a different way to capture the relationship between a type like "u8", a structured vector type like "u8x16" and an Intel type like __m128i. This resulted in a fairly complete rewrite of what was there before.</li>
<li>It supports all the intrinsics I see in<ul>
<li>the cloudflare sliceslice-rs  <a href="https://github.com/cloudflare/sliceslice-rs/blob/master/src/x86.rs#L50-L127">https://github.com/cloudflare/sliceslice-rs/blob/master/src/x86.rs#L50-L127</a></li>
<li>aho-corasick <a href="https://github.com/BurntSushi/aho-corasick/blob/master/src/packed/vector.rs">https://github.com/BurntSushi/aho-corasick/blob/master/src/packed/vector.rs</a></li>
</ul>
</li>
<li>It is currently missing a few intrinsics used in hashbrown - by the time some of you read this, this should be fixed :-)</li>
</ul>
</li>
</ul>
<p>This is sufficient that I can emulate all of the simd intrinsics that I find in coreutils and all the crates that it depends on.</p>
<p>Notes:</p>
<ul>
<li>I have not tested any of the intrinsics and I don't understand the naming conventions so there are certain to be bugs.<ul>
<li>There are tests in core_arch that is might be possible to run? <a href="https://github.com/rust-lang/stdarch/blob/master/crates/core_arch/src/x86/sse2.rs#L3083">https://github.com/rust-lang/stdarch/blob/master/crates/core_arch/src/x86/sse2.rs#L3083</a></li>
</ul>
</li>
<li>I have not tried to implement all the SSE2 intrinsics<ul>
<li>It meets my current research purposes but I would love to work with others to make it complete, test it, etc. and turn it into a reliable thing that people (and, in particular, miri) can use</li>
</ul>
</li>
<li>I have implemented some AVX2 intrinsics as well<ul>
<li>In theory, you can use feature flags to disable AVX2 so we don't really need these.</li>
<li>In practice, it may be easier if things just work without messing around with how things are built or requiring all code to have a generic fallback.</li>
</ul>
</li>
<li>I have not implemented intrinsics for Arm Neon, SVE, etc. yet<ul>
<li>I suspect that I will need this soon so the traits etc. used to implement intrinsics is written with that in mind</li>
</ul>
</li>
<li>There is a lot of repetition involved in supporting vectors that can have 2, 4, 8, 16 or 32 lanes and in supporting operations that take two vectors and return a vector, that take a vector and scalar and return a vector, etc.<ul>
<li>I would welcome suggestions on how to use macros to capture more of the structure here. (I am not a macros expert)</li>
</ul>
</li>
<li>The 'for_miri' module is intended to match what Miri needs.<ul>
<li>I am just guessing what it needs - let's change it as needed to make Miri happy.</li>
</ul>
</li>
</ul>



<a name="234518574"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234518574" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234518574">(Apr 14 2021 at 15:18)</a>:</h4>
<blockquote>
<p>to have a suitable way of converting from the intrinsic names in MIR to the name of the emulation function</p>
</blockquote>
<p>for the generic <code>simd_*</code> intrinsics, there are few enough that it might be easier to implement them in the miri interpreter instead of dispatching to MIR... not sure.</p>



<a name="234518671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234518671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234518671">(Apr 14 2021 at 15:19)</a>:</h4>
<blockquote>
<p>for the generic intrinsics like "simd_and", I suspect that you would need to use the vector length to produce a unique name (eg "simd_and_128")</p>
</blockquote>
<p>why that? the best thing for Miri would be for the intrinsic implementation to be generic the same way the intrinsic is.</p>



<a name="234518939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234518939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234518939">(Apr 14 2021 at 15:20)</a>:</h4>
<p>Probably we'd have to add trait bounds like <code>T: Add</code> to actually implement them, and risk ICEs if we call it for types that do not implement the trait, but ICEs for misused intrinsics are okay</p>



<a name="234519605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234519605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234519605">(Apr 14 2021 at 15:23)</a>:</h4>
<div class="codehilite"><pre><span></span><code>// For LLVM purposes, we _must_ use the structured types.
// For Miri purposes, we probably need to use the Intel types.
</code></pre></div>
<p>Interesting, I am curious why LLVM needs the structured types.<br>
for Miri, the types should be <em>exactly</em> like they are in the intrinsic imports, like <a href="https://github.com/rust-lang/stdarch/blob/6495bb0e33578443c21764655a4dd8b55399c008/crates/core_arch/src/x86/sse2.rs#L2855">e.g. here</a></p>



<a name="234519711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234519711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234519711">(Apr 14 2021 at 15:23)</a>:</h4>
<p>it looks like that is using the structured types, which would explain why for LLVM purposes you want that, and would mean Miri also wants structured types</p>



<a name="234528188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234528188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234528188">(Apr 14 2021 at 16:12)</a>:</h4>
<p>Ah, as a data point of something that covers nearly all stable intrinsics (all the ones that can be made safe that is), check the <a href="https://github.com/Lokathor/safe_arch">safe_arch</a> crate. The test suite is in the process of being rewritten from doc tests to integration tests, but everything should have at least one test, so using it as a "coverage check" for miri might be a reasonable thing to do.</p>



<a name="234529555"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234529555" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alastair Reid <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234529555">(Apr 14 2021 at 16:20)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> The key thing with types is that every tool needs the SIMD emulation functions to have the same type as the intrinsic that it is replacing.</p>
<p>For LLVM-based tools, I see functions with the LLVM type "declare i32 @llvm.x86.sse2.pmovmskb.128(&lt;16 x i8&gt;)" so I make sure that I am using a Rust type with that representation for that function.  I can check it by compiling with --emit-ir and searching the resulting .ll file for intrinsic names and emulation function names.</p>
<p>For miri, I am assuming that this is a type like __m128i. [Although, as I type these words, I am increasingly doubtful that this could possibly be what miri needs...]<br>
Really, I have just been guessing. If you tell me what you need (and ideally how to check what I am currently generating), I'm super-happy to change it.</p>



<a name="234537048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234537048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234537048">(Apr 14 2021 at 17:07)</a>:</h4>
<blockquote>
<p>For miri, I am assuming that this is a type like __m128i. [Although, as I type these words, I am increasingly doubtful that this could possibly be what miri needs...]<br>
Really, I have just been guessing. If you tell me what you need (and ideally how to check what I am currently generating), I'm super-happy to change it.</p>
</blockquote>
<p>What Miri needs is for the type to match exactly the type used in the <code>extern</code> block that stdarch uses to import these intrinsics.</p>



<a name="234537098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234537098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234537098">(Apr 14 2021 at 17:07)</a>:</h4>
<p><a href="https://github.com/rust-lang/stdarch/blob/6495bb0e33578443c21764655a4dd8b55399c008/crates/core_arch/src/x86/sse2.rs#L2855">This seems to match</a> what you see in LLVM IR, though I am not sure how <code>i32x4</code> and friends as used in this file are defined.</p>



<a name="234537616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234537616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234537616">(Apr 14 2021 at 17:10)</a>:</h4>
<p>I assume the type is being defined <a href="https://github.com/rust-lang/stdarch/blob/6495bb0e33578443c21764655a4dd8b55399c008/crates/core_arch/src/simd.rs#L243">here</a></p>



<a name="234547357"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234547357" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alastair Reid <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234547357">(Apr 14 2021 at 18:08)</a>:</h4>
<p>Ah, I had somehow gotten the idea that Miri needed something else.<br>
So, just to be absolutely clear, there are two things defined for most/all intrinsics in stdarch.</p>
<p>First, there is an extern blocks that looks like this <a href="https://github.com/rust-lang/stdarch/blob/master/crates/core_arch/src/x86/sse2.rs#L2809">https://github.com/rust-lang/stdarch/blob/master/crates/core_arch/src/x86/sse2.rs#L2809</a></p>
<div class="codehilite"><pre><span></span><code>#[allow(improper_ctypes)]
extern &quot;C&quot; {
    ...
    #[link_name = &quot;llvm.x86.sse2.pavg.b&quot;]
    fn pavgb(a: u8x16, b: u8x16) -&gt; u8x16;
    ...
}
</code></pre></div>
<p>The types are what I need to use with LLVM and also what you need for Mir</p>
<p>There is also a wrapper that corresponds to the intrinsic names and types that Intel use in their C intrinsics header file</p>
<div class="codehilite"><pre><span></span><code>#[inline]
#[target_feature(enable = &quot;sse2&quot;)]
#[cfg_attr(test, assert_instr(pavgb))]
#[stable(feature = &quot;simd_x86&quot;, since = &quot;1.27.0&quot;)]
pub unsafe fn _mm_avg_epu8(a: __m128i, b: __m128i) -&gt; __m128i {
    transmute(pavgb(a.as_u8x16(), b.as_u8x16()))
}
</code></pre></div>
<p>I think we are saying that neither of us need that and we can ignore it.</p>
<p>I am trying to be explicit about this because I have been a bit confused about this up until now.<br>
I look in source code and I see the wrappers being called with their types but I look in LLVM bitcode files and I see the intrinsics with their different types.</p>



<a name="234547503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234547503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alastair Reid <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234547503">(Apr 14 2021 at 18:09)</a>:</h4>
<p>(I feel yet another rewrite of my emulation library coming on... using the type definitions you point at and using the extern block as my sole source of information about the type of each intrinsic.)</p>



<a name="234640764"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234640764" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234640764">(Apr 15 2021 at 09:02)</a>:</h4>
<blockquote>
<p>I think we are saying that neither of us need that and we can ignore it.</p>
</blockquote>
<p>Yes. That wrapper has a MIR body which Miri can just evaluate.  Then at some point the code will call a function from the <code>extern</code> block that does <em>not</em> have a MIR body, and this is where Miri gets stuck.</p>



<a name="234640842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/269128-miri/topic/simd%20support/near/234640842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/269128-miri/topic/simd.20support.html#234640842">(Apr 15 2021 at 09:03)</a>:</h4>
<blockquote>
<p>I look in source code and I see the wrappers being called with their types but I look in LLVM bitcode files and I see the intrinsics with their different types.</p>
</blockquote>
<p>I assume the wrappers have all been inlined?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>